Skip to content

Versioning#263

Open
Sdoba16 wants to merge 4 commits into
BlockstreamResearch:masterfrom
Sdoba16:feature/versions
Open

Versioning#263
Sdoba16 wants to merge 4 commits into
BlockstreamResearch:masterfrom
Sdoba16:feature/versions

Conversation

@Sdoba16

@Sdoba16 Sdoba16 commented Mar 31, 2026

Copy link
Copy Markdown
Collaborator

Closes #248

Add compiler versioning for SimplicityHL contracts

This PR introduces strict compiler version requirements

  • Version Directives: Every .simf file must now begin with a simc "..." directive. The directive is safely extracted (ignoring comments) and validated before full AST construction.
  • SemVer Ranges: Added support for standard Semantic Versioning ranges (e.g., >=0.6.0, ^0.6.0, ~0.6.0)
  • Dependency Versioning: The compiler driver now verifies version compatibility across the entire multi-file project (main.simf and all imported --dep libraries)
  • Developer Tooling: Added update_examples.py and a CI workflow to easily manage version across all examples and tests.

Syntax:

simc ">=0.6.0";

fn main() {
    ...
}

Needed simplex addition for this PR:

  • Version Installer: Tooling that will go through the dependencies and look for best fitting version to be installed. The tool will take existing versions from HL releases and install the best-fitted one.

@Sdoba16 Sdoba16 closed this Mar 31, 2026
@Sdoba16 Sdoba16 reopened this Mar 31, 2026
@Sdoba16 Sdoba16 self-assigned this Mar 31, 2026

@stringhandler stringhandler left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concept ACK.

I've come around to the idea that users should optionally be able to specify the compiler version. However, I don't like the pragma keyword as it deviates from rust, which we haven't done previously. Below are some suggestions.

I also don't think it should be required in the .simc, which will allow us to specify it in a project level manifest for when multiple files are included and for libraries in future. Also, the user should not be forced to provided it even in a single file scenario. This is just extra friction for new developers.

Comment thread examples/array_fold.simf Outdated
@@ -1,3 +1,5 @@
pragma version 0.5.0-rc.0;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we maybe rather use a global attribute syntax

#![version("0.5.0-rc.0")]

I would also suggest naming it compiler-version or simc_version or even just simc, so that users don't think it is annotating this file with a version.

Comment thread src/error.rs Outdated
/// Records _what_ happened but not where.
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub enum Error {
VersionMismatch {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
VersionMismatch {
SimcVersionMismatch {

I prefer stating that it's the compiler version here as well

Comment thread src/ast.rs Outdated

let insertion_point = Span::new(first_item_span.start, first_item_span.start);

return Err(Error::MissingPragma {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think pragmas should be optional

Comment thread src/error.rs Outdated
expected: String,
compiler: String,
},
MissingPragma {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think stating the compiler version should be required

@apoelstra

Copy link
Copy Markdown
Contributor

ab41fec needs rebase

@Sdoba16 Sdoba16 force-pushed the feature/versions branch 3 times, most recently from ef379ee to 975817b Compare April 6, 2026 10:59
@Sdoba16 Sdoba16 force-pushed the feature/versions branch from 975817b to 48917f7 Compare May 4, 2026 13:23
@Sdoba16 Sdoba16 requested review from apoelstra May 4, 2026 13:41
@Sdoba16 Sdoba16 force-pushed the feature/versions branch from e4551f5 to c56e75d Compare May 4, 2026 13:56
@Sdoba16 Sdoba16 marked this pull request as ready for review May 5, 2026 08:17
@Sdoba16 Sdoba16 requested a review from delta1 as a code owner May 5, 2026 08:17
@KyrylR

KyrylR commented May 8, 2026

Copy link
Copy Markdown
Collaborator

Do we have an issue for discussion this?

@Sdoba16

Sdoba16 commented May 8, 2026

Copy link
Copy Markdown
Collaborator Author

Do we have an issue for discussion this?

#248

@LesterEvSe LesterEvSe linked an issue May 15, 2026 that may be closed by this pull request
@KyrylR

KyrylR commented Jun 1, 2026

Copy link
Copy Markdown
Collaborator

Needs rebase

@apoelstra

Copy link
Copy Markdown
Contributor

c56e75d needs rebase

@Sdoba16 Sdoba16 force-pushed the feature/versions branch from c56e75d to 18ab20c Compare June 3, 2026 16:57
Comment thread doc/versioning.md Outdated
Comment thread doc/versioning.md Outdated
Comment thread src/driver/version_tests.rs Outdated
Comment thread src/driver/version_tests.rs Outdated
@stringhandler

Copy link
Copy Markdown
Contributor

Is it required to add the compiler version? I would say the examples should only specify the minimum version needed to compile, which for all of these would not be necessary as they don't have any breaking changes. The only ones that might need to be specified are the ones using the use and pub keywords.

It is generally fine to include a compiler version, but these look like they need to keep being updated.

Comment thread examples/local_crate/main.simf Outdated
@@ -1,3 +1,5 @@
simc ">=0.6.0";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this not just be simc "0.6.0"?

Can we guarantee it will work on 0.7.0?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I explained the reason here: #263 (comment)

Comment thread doc/versioning.md Outdated

The SimplicityHL compiler enforces strict version compatibility to prevent contracts from silently breaking due to compiler updates, semantic changes, or new language features.

Every `.simf` file must begin with a compiler version directive:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Every `.simf` file must begin with a compiler version directive:
Every `.simf` file may begin with a compiler version directive:

I think it is incredibly limiting to new developers to enforce this. Surely this should be opt-in.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not fully understand how it will work. If we load a file without a version, then how are we supposed to determine it? Do we assume that it is always correct? What if the functionality in that file becomes deprecated? What if we have some vulnerabilities in the file? Thus, I think we need to make it mandatory for users to use versions

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me walk through the two concrete scenarios:

Case 1: File uses newer syntax (e.g., pub or use, introduced in simc 0.6.0)
If no version is specified, the file simply fails to compile on older compilers with a syntax error. The simc field doesn't change this outcome - it just gives a much better error message ("this file requires simc >= 0.6.0") instead of a confusing parser error.

Case 2: File uses deprecated or removed functionality
Same story: without a version constraint, the file fails to compile once that feature is removed. The simc field lets authors signal simc >=0.5.0, <0.6.0 to make that explicit, but it's still an error either way.

On vulnerabilities: the simc version field controls compilation compatibility, not runtime security. Vulnerabilities in Simplicity programs are addressed at the consensus/jet layer, independently of the compiler version.

So omitting the simc field is never silently wrong - the compiler still catches incompatibilities. Making it mandatory adds friction for new developers who just want to write a simple program, and requires them to understand version semantics before writing their first line of code. Keeping it as may means it's there when you need better error messages, but doesn't block the happy path.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, okay

Comment thread src/driver/mod.rs Outdated
for (path, content) in files {
let full_path = format!("workspace/{}", path);
let created_file = canon(&ws.create_file(&full_path, content));
let injected_content = if crate::version::has_version_header(content)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could use a comment.

Comment thread src/driver/version_tests.rs Outdated

version_test!(
exact_match_all, true, None,
"main.simf" => "simc \"={v}\";\nuse lib::A::foo;\nfn main() {}",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"main.simf" => "simc \"={v}\";\nuse lib::A::foo;\nfn main() {}",
"main.simf" => r#"simc ""={v}"";
use lib::A::foo;
fn main() {}"#,

These would be much easier to review if you use raw strings

@apoelstra

Copy link
Copy Markdown
Contributor

cd5b1e9 needs rebase

@Sdoba16 Sdoba16 marked this pull request as draft June 26, 2026 09:07
@Sdoba16 Sdoba16 force-pushed the feature/versions branch 3 times, most recently from 521e33f to 1ac6efd Compare June 29, 2026 10:03
@Sdoba16 Sdoba16 force-pushed the feature/versions branch 2 times, most recently from a413ba1 to fed34ae Compare July 1, 2026 07:17
@Sdoba16 Sdoba16 marked this pull request as ready for review July 1, 2026 07:28
@Sdoba16 Sdoba16 requested a review from LesterEvSe July 1, 2026 07:32
@Sdoba16 Sdoba16 force-pushed the feature/versions branch from fed34ae to 948b18d Compare July 1, 2026 08:47
Comment thread src/version.rs
Comment on lines +179 to +181
/// Replace the directive with equal-length spaces so the parser never sees it
/// while later byte offsets (and thus error spans) stay correct.
pub(crate) fn blank_version_directive(content: &str) -> Cow<'_, str> {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function answers the question "What does this function do?", but not "Why was this function needed?". I looked at the following commits to see its usage inside the parse.rs file, but I still do not understand the reason for using it

Comment thread src/version.rs
Comment on lines +232 to +237
/// A directive-looking line that is not a well-formed `simc "...";`.
Malformed(Span),
/// More than one directive.
Duplicate(Span),
/// A well-formed directive that appears after program code.
Misplaced(Span),

@LesterEvSe LesterEvSe Jul 1, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's stick to the style that was mentioned here: #328 (comment)

Comment thread src/tracker.rs

#[test]
fn test_debug_and_jet_tracing() {
let program_text = TEST_PROGRAM;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not think we need to change this file at all

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: Versioning

5 participants